import useAppStore from '~/stores/app'
import useUserStore from '~/stores/user'
import { popupEnum } from '~/enums/app'
import type { DrawFormData, DrawOptions } from '../types/draws'
import drawingApi from '~/api/apply/draws/drawing'

export const option: Ref<DrawOptions[]> = ref<DrawOptions[]>([])  // 绘画接口
export const config: Ref<Record<string, any>> = ref({})           // 绘画配置
export const createLoading: Ref<boolean> = ref<boolean>(false)    // 生成按钮加载动画

export const formData: Ref<DrawFormData> = ref<DrawFormData>({
    engine: 'mj',             //【是】绘图接口: [mj, sd, dalle3]
    action: 'generate',       //【是】操作类型: [generate=生成图片, upsample{index}=放大, variation{index}=变换]
    model: 'mj',              //【是】绘画模型
    scale: '1:1',             //【是】图片比列
    prompt_in: '',            //【是】原始提示词
    prompt_en: '',            //【是】英文提示词
    version: '',              //【否】版本参数
    image_id: '',             //【否】图片的ID
    image_ref: '',            //【否】参考图片
    other_params: {},         //【否】其它参数
    complex_params: {}        //【否】高级参数
})

/**
 * 查询记录参数
 *
 * @author zero
 */
export const queryParams = reactive<{ status: number, engine: string }>({
    engine: formData.value.engine,
    status: -1
})

/**
 * 获取绘画记录
 *
 * @author zero
 */
export const { pager, queryLists } = usePaging({
    fetchFun: drawingApi.record,
    params: queryParams
})

/**
 * 获取绘画配置
 *
 * @author zero
 */
export const getDrawConfig = async (): Promise<void> => {
    const data: DrawsConfigResponse = await drawingApi.config(formData.value.engine)
    option.value = data.options
    config.value = data.configs
}

/**
 * 重置绘画参数
 *
 * @param {Partial<DrawFormData>} params
 * @author zero
 */
export const resetFormData = async (params?: any): Promise<void> => {
    queryParams.engine = params?.engine || ''
    if (params) {
        formData.value = {
            ...formData.value,
            ...params
        }
    }
}

/**
 * 生成绘画任务
 *
 * @param {Partial<DrawFormData>} data
 * @author zero
 */
export const generate = async (data: DrawFormData | any): Promise<void> => {
    const appStore = useAppStore()
    const userStore = useUserStore()
    if (!userStore.isLogin) {
        return appStore.setPopup(popupEnum.LOGIN)
    }

    try {
        end()
        queryParams.engine = data.engine
        createLoading.value = true
        await drawingApi.generate(data)
        await queryLists()
        await getDrawConfig()
        await resetFormData({
            prompt_in: '',
            prompt_en: ''
        })
        setTimeout((): void => {
            createLoading.value = false
        }, 2000)
        start()
    } catch {
        createLoading.value = false
    } finally {
        await resetFormData({action: 'generate'})
    }
}

/**
 * 心跳检测完成状态
 *
 * @author zero
 */
const checkDrawsStatus = async (): Promise<void> => {
    // 获取任务ID
    const taskIds: string[] = pager.lists
        .filter((item: any) => {
            return item.status === 1 || item.status === 0
        })
        .map((item: any) => item.code)

    // 结束心跳任务
    if (taskIds.length <= 0) {
        return end()
    }

    // 更新数据信息
    const results: DrawsRecordResponse[] = await drawingApi.detection(taskIds)
    results.forEach((item: DrawsRecordResponse): void => {
        const code: string = item.code
        for (let i: number = 0; i < pager.lists.length; i++) {
            if (code === pager.lists[i].code &&
                pager.lists[i].status !== item.status
            ) {
                pager.lists[i] = item
                break
            }
        }
    })
}

/**
 * 心跳检测任务结束
 *
 * @author zero
 */
const endDrawsCallback = async (): Promise<void> => {
    end()
    const userStore = useUserStore()
    await userStore.getUser()
    await queryLists()
}

/**
 * 轮询更新任务状态
 */
const { start, end } = usePolling(checkDrawsStatus, {
    key: 'draws',
    time: 1000 * 10,
    totalTime: 10 * 60 * 1000,
    callback: endDrawsCallback
})

watch(
    () => queryParams.status,
    (): void => {
        start()
    }, { immediate: true }
)
